package boot.spring.controller;

import java.util.List;
import java.util.Map;

import org.redisson.api.GeoEntry;
import org.redisson.api.GeoPosition;
import org.redisson.api.GeoUnit;
import org.redisson.api.RAtomicDouble;
import org.redisson.api.RBucket;
import org.redisson.api.RDoubleAdder;
import org.redisson.api.RGeo;
import org.redisson.api.RLongAdder;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import boot.spring.po.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "分布式对象")
@RestController
@RequestMapping("/object")
public class ObjectController {
    @Autowired
    RedissonClient redissonClient;

    @ApiOperation("地理空间对象")
    @GetMapping("/geo")
    public AjaxResult geo() {
        RGeo<String> geo = redissonClient.getGeo("geo");
        geo.add(new GeoEntry(116.4072154982, 39.9047253699, "北京"),
                new GeoEntry(121.4737919321, 31.2304324029, "上海"));
        geo.addAsync(114.10000, 22.20000, "香港");
        // 计算北京上海的距离
        Double distance = geo.dist("北京", "上海", GeoUnit.KILOMETERS);
        System.out.println("北京到上海距离是" + distance + "千米");
        //GeoHash:一个字符串表示经度和纬度两个坐标,代表一个矩形区域
        Map<String, String> map = geo.hash("北京", "上海", "香港");
        System.out.println("北京的Geo哈希值为" + map.get("北京"));
        Map<String, GeoPosition> positions = geo.pos("北京", "上海", "香港");
        System.out.println("各城市名称和经纬度是" + positions);
        // 圆形搜索，圆心是石家庄，检索半径400千米
        List<String> cities = geo.radius(114.52 , 38.05, 400, GeoUnit.KILOMETERS);
        System.out.println("搜索结果有" + cities);
        Map<String, GeoPosition> citiesWithPositions = geo.radiusWithPosition(114.52 , 38.05, 400, GeoUnit.KILOMETERS);
        return AjaxResult.success(citiesWithPositions);
    }

    @ApiOperation("原子双精度浮点数")
    @GetMapping("/AtomicDouble")
    public AjaxResult rAtomicDouble(@RequestParam Double a, @RequestParam Double b) {
        RAtomicDouble atomicDouble = redissonClient.getAtomicDouble("atDouble");
        atomicDouble.set(a);
        atomicDouble.addAndGet(b);
        return AjaxResult.success(atomicDouble.get());
    }

    @ApiOperation("双精度浮点累加器，性能比AtomicDouble快1万倍")
    @GetMapping("/DoubleAdder")
    public AjaxResult rDoubleAdder(@RequestParam Double a, @RequestParam Double b) {
        RDoubleAdder doubleAddr = redissonClient.getDoubleAdder("doubleAddr");
        try {
            doubleAddr.add(a);
            doubleAddr.add(b);
            doubleAddr.increment();
            return AjaxResult.success(doubleAddr.sum());
        } finally {
            doubleAddr.destroy();
        }
    }

    @ApiOperation("整长型累加器")
    @GetMapping("/RLongAdder")
    public AjaxResult rRLongAdder(@RequestParam Long a, @RequestParam Long b) {
        RLongAdder longAddr = redissonClient.getLongAdder("longAddr");
        try {
            longAddr.add(a);
            longAddr.add(b);
            longAddr.increment();
            return AjaxResult.success(longAddr.sum());
        } finally {
            longAddr.destroy();
        }
    }
}